using System;
using System.IO;
using PublicDomain.Copy;
using SevenZSharp.CommandLine;
using SevenZSharp.Engines;

namespace SevenZSharp.Encoders
{
   /// <summary>
   /// 
   /// </summary>
   public class ShellEncoder : CompressionEncoder
   {
      private readonly ShellEngine m_engine;

      /// <summary>
      /// Initializes a new instance of the <see cref="ShellEncoder"/> class.
      /// </summary>
      /// <param name="engine">The engine.</param>
      public ShellEncoder(ShellEngine engine)
      {
         m_engine = engine;
      }

      /// <summary>
      /// Encodes a single file. <paramref name="inStream"/> is the non-encoded
      /// file which will be encoded and placed into <paramref name="outStream"/>.
      /// If <paramref name="outStream"/> does not exist, it will be created.
      /// </summary>
      /// <param name="inStream">The in stream.</param>
      /// <param name="outStream">The out stream.</param>
      public override void EncodeSingleFile(FileStream inStream, FileStream outStream)
      {
         EncodeSingleFile(inStream.Name, outStream.Name);
      }

      /// <summary>
      /// Encodes a single file. <paramref name="inFile"/> is the path to the non-encoded
      /// file which will be encoded and placed into <paramref name="outFile"/>.
      /// If <paramref name="outFile"/> does not exist, it will be created.
      /// </summary>
      /// <param name="inFile">The in file.</param>
      /// <param name="outFile">The out file.</param>
      public override void EncodeSingleFile(string inFile, string outFile)
      {
         EncodeFromDirectory(inFile, outFile);
      }

      /// <summary>
      /// Recursively encodes all files in the specified <paramref name="inDirectory"/> and
      /// writes the archive into the specified <paramref name="outFile"/>. If <paramref name="outFile"/>
      /// does not exist, it will be created.
      /// </summary>
      /// <param name="inDirectory">The in directory.</param>
      /// <param name="outFile">The out file.</param>
      public override void EncodeFromDirectory(string inDirectory, string outFile)
      {
         CompressionFormat format = CompressionEngine.InferCompressionFormat(outFile);
         switch (format)
         {
            case CompressionFormat.SevenZ:
            case CompressionFormat.Zip:
            case CompressionFormat.Gzip:
            case CompressionFormat.Bzip2:
            case CompressionFormat.Tar:

               string type = ArchiveTypes.GetArchiveType(format);
               ProcessHelper process = m_engine.GetShellProcess();
               process.AddArguments("a", "-bd", "-y");
               process.AddArguments("-t" + type);
               process.AddArguments(outFile);
               process.AddArguments(inDirectory);
               process.StartAndWaitForExit(true);
               break;
            default:
               throw new NotImplementedException("Encoding into CompressionFormat " + format + " not supported");
         }
      }
   }
}